package com.xiaokan.frame;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.xiaokan.agent.CheckerAgentThread;
import com.xiaokan.model.Configuration;

public class MainFrame extends JFrame {

	private JPanel contentPane;
	private final DrawPanel drawPanel;
	private boolean isStarted = false;
	private MouseAdapter ma;
	private byte humanSide, agentSide;
	private CheckerAgentThread agentThread;
	private final JTextArea textArea;
	private int level;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainFrame() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 441, 618);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		drawPanel = new DrawPanel();
		ma = new CheckerMouseAdapter(this.drawPanel);

		drawPanel.setBounds(10, 11, 402, 402);
		drawPanel.setParentFrame(this);
		drawPanel.reset();

		contentPane.add(drawPanel);

		JButton btnStart = new JButton("Start");

		btnStart.setBounds(146, 524, 62, 23);
		contentPane.add(btnStart);

		textArea = new JTextArea();
		textArea.setBounds(10, 424, 402, 80);
		contentPane.add(textArea);

		final JRadioButton blackRadioButton = new JRadioButton("Black");
		blackRadioButton.setSelected(true);
		blackRadioButton.setBounds(10, 511, 62, 23);
		contentPane.add(blackRadioButton);

		final JRadioButton whiteRadioButton = new JRadioButton("White");
		whiteRadioButton.setBounds(74, 511, 65, 23);
		contentPane.add(whiteRadioButton);

		final JSpinner spinner = new JSpinner();
		spinner.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				level = (int) spinner.getValue();
			}
		});
		spinner.setModel(new SpinnerNumberModel(4, 1, 4, 1));
		spinner.setBounds(74, 540, 56, 20);
		contentPane.add(spinner);

		JLabel lblDifficulty = new JLabel("Difficulty");
		lblDifficulty.setBounds(20, 541, 58, 17);
		contentPane.add(lblDifficulty);

		ButtonGroup bg = new ButtonGroup();
		bg.add(blackRadioButton);
		bg.add(whiteRadioButton);

		JButton btnStop = new JButton("Stop");
		btnStop.addActionListener(new ActionListener() {
			// stop
			public void actionPerformed(ActionEvent e) {
				if (isStarted) {
					textArea.setText(textArea.getText() + "Program ends\n");
					drawPanel.removeMouseListener(ma);
					isStarted = false;
					spinner.setEnabled(true);
					blackRadioButton.setEnabled(true);
					whiteRadioButton.setEnabled(true);
					agentThread.interrupt();
				} else {
					textArea.setText(textArea.getText() + "Program already ended\n");
				}
			}
		});
		btnStop.setBounds(218, 524, 62, 23);
		contentPane.add(btnStop);

		btnStart.addActionListener(new ActionListener() {
			// start
			public void actionPerformed(ActionEvent e) {
				if (isStarted) {
					textArea.setText(textArea.getText() + "Program already started\n");
				} else {
					spinner.setEnabled(false);
					drawPanel.reset();
					drawPanel.repaint();
					boolean startNow = false;
					if (blackRadioButton.isSelected()) {
						humanSide = Configuration.BLACK;
						agentSide = Configuration.WHITE;
					} else {
						startNow = true;
						humanSide = Configuration.WHITE;
						agentSide = Configuration.BLACK;
					}
					agentThread = new CheckerAgentThread(agentSide);
					agentThread.setAgentSide(agentSide);
					agentThread.setHumanSide(humanSide);
					agentThread.setLevel(level);
					agentThread.setConfig(drawPanel.getConfig());
					agentThread.reset();
					agentThread.start();
					drawPanel.setAgentThread(agentThread);
					blackRadioButton.setEnabled(false);
					whiteRadioButton.setEnabled(false);
					drawPanel.getConfig().init();
					agentThread.setConfig(drawPanel.getConfig());
					isStarted = true;
					textArea.setText(textArea.getText() + "Program starts\n");
					drawPanel.addMouseListener(ma);
					if (startNow) {
						synchronized (this) {
							agentThread.notify();
						}
						drawPanel.repaint();
					}
				}
			}
		});

	}

	public void gameOver() {
		int utility = agentThread.utility();
		String result;
		if (utility > 0)
			result = "Computer Wins!\n";
		else if (utility == 0) {
			result = "Draw game!\n";
		} else
			result = "You wins!\n";
		textArea.setText(textArea.getText() + "Game over, " + result);
		drawPanel.removeMouseListener(ma);
		agentThread.interrupt();
		isStarted = false;
	}

	public byte getHumanSide() {
		return humanSide;
	}

	public void setHumanSide(byte humanSide) {
		this.humanSide = humanSide;
	}

	public byte getAgentSide() {
		return agentSide;
	}

	public void setAgentSide(byte agentSide) {
		this.agentSide = agentSide;
	}

	public JTextArea getTextArea() {
		return textArea;
	}

	public CheckerAgentThread getAgentThread() {
		return agentThread;
	}

	public void setAgentThread(CheckerAgentThread agentThread) {
		this.agentThread = agentThread;
	}

}
